package at.ac.tuwien.swa.sparrow.server.controller

import at.ac.tuwien.swa.sparrow._
import at.ac.tuwien.swa.sparrow.common._
import at.ac.tuwien.swa.sparrow.server._
import at.ac.tuwien.swa.sparrow.server.component.{BillingEngine, PeerManager, UserManager}
import at.ac.tuwien.swa.sparrow.server.persistence.AccountRepository
import at.ac.tuwien.swa.sparrow.server.security.{SecurityContext, Secured}
import com.google.common.net.HostAndPort
import java.util.UUID
import javax.inject.Inject
import org.springframework.stereotype.Controller

@Controller
class PeerController @Inject()(peerManager: PeerManager, userManager: UserManager, billingEngine: BillingEngine,
															 accountRepository: AccountRepository) extends PeerService {

	@Secured() def register(username: String, password: String): UUID = peerManager.register(username, password)

	@Secured() def login(peerId: UUID, address: HostAndPort) = {
		val peer = peerManager.login(peerId, address)
		SecurityContext.setRole(peer)
		new PeerInfo(peer)
	}

	@Secured(classOf[Peer]) def logout(peerId: UUID) {
		peerManager.logout(peerId)
		SecurityContext.setRole(null)
	}

	@Secured(classOf[Peer]) override def lookup(n: Int): Set[PeerInfo] = onlinePeerInfo subset n

	@Secured(classOf[Peer]) override def lookup(exclude: Set[HostAndPort] = Set.empty, n: Int = 10): Set[PeerInfo] =
		onlinePeerInfo filterNot (p => exclude contains p.address) subset n

	private def onlinePeerInfo = {
		peerManager.onlinePeers map (p => PeerInfo(p.id, p.address, p.lastOnline, p.online))
	}

	@Secured(classOf[Peer]) override def update(peerInfo: Set[PeerInfo]) {
		peerInfo foreach peerManager.update
	}

	@Secured(classOf[Peer]) override def update(ticket: Ticket, trackInfo: Option[TrackInfo]) {
		peerManager.update(ticket, trackInfo)
	}

}
